-- 运营活动: 达标竞技


--[[
{   --第一天
    {
        online = 900,   --当天累积在线时间（秒）15分钟
        awards = 
        {               
            {type = 0, id = 513, count = 1, quality = 0, strong = 0, bind = 1},
            {type = 0, id = 645, count =10, quality = 0, strong = 0, bind = 1},
        },
        goldGetConsumes =
        {
            {type = 0, id = 645, count =10, quality = 0, strong = 0, bind = 1},
        }, 
    },
    --第2次
    {
        online = 2400,  --当天累积在线时间（秒）40分钟
        awards = 
        {               
            {type = 0, id = 513, count = 1, quality = 0, strong = 0, bind = 1},
            {type = 0, id = 645, count =15, quality = 0, strong = 0, bind = 1},
        },
        goldGetConsumes =
        {
            {type = 0, id = 645, count =10, quality = 0, strong = 0, bind = 1},
        }, 
    },
    --第3次
    {
        online = 4500,  --当天累积在线时间（秒）75分钟
        awards = 
        {               
            {type = 0, id = 513, count = 1, quality = 0, strong = 0, bind = 1},
            {type = 0, id = 645, count =20, quality = 0, strong = 0, bind = 1},
        },
        goldGetConsumes =
        {
            {type = 0, id = 645, count =10, quality = 0, strong = 0, bind = 1},
        }, 
    },
    --第4次
    {
        online = 7200,  --当天累积在线时间（秒）120分钟
        awards = 
        {               
            {type = 0, id = 513, count = 2, quality = 0, strong = 0, bind = 1},
            {type = 0, id = 834, count =10, quality = 0, strong = 0, bind = 1},
        },
        goldGetConsumes =
        {
            {type = 0, id = 645, count =10, quality = 0, strong = 0, bind = 1},
        }, 
    },
},
]]

-- 检查配置是否正确，正确则返回 0，否则返回错误码
function oper_act_94_check_cfg(cfg)
    if cfg == nil then return 20 end
    
    local config = cfg.config
    if config == nil then return 21 end
    
    if config.Rewards == nil then return 23 end
    if type(config.Rewards) ~= "table" then return 24 end
    for idx = 1, #config.Rewards do
        local dayRewards = config.Rewards[idx]
        if dayRewards == nil then return 25 end
        if type(dayRewards) ~= "table" then return 26 end
        for ii = 1, #dayRewards do
            if dayRewards[ii] == nil then return 27 end
            if type(dayRewards[ii]) ~= "table" then return 28 end
            if dayRewards[ii].awards == nil then return 29 end
            if type(dayRewards[ii].awards) ~= "table" then return 30 end
            if not oper_act_check_one_award_cfg(dayRewards[ii].awards) then
                return 22
            end 
        end
    end
    if config.showReward == nil then return 31 end
    if type(config.showReward) ~= "table" then return 32 end
    
    if not oper_act_check_one_award_cfg(config.showReward) then
        return 22
    end 

    return 0
end

-- 安装活动，成功则返回 0，否则返回错误码
function oper_act_94_setup(cfg)  
    return 0
end

-- 卸载活动
function oper_act_94_unsetup(cfg)    
end

-- 活动开始
function oper_act_94_start(cfg)
    local ssVar = System.getStaticVar()
    ssVar.oper_act_94_start = 1
    ssVar.oper_act_94_cmd = cfg.cmd_id
    ssVar.oper_act_94_act = cfg.act_id

    local data = gRankMgr_GetValueByIndx(0, RANK_DEFINE_OPERATION_94, 1)

    if data then
        local myData = BaseFuc_unserialize(data)
        if myData and myData.cmd_id and myData.cmd_id == cfg.cmd_id and myData.act_id and myData.act_id == cfg.act_id and
            myData.time and cfg.beg_time <= myData.time and  cfg.end_time > myData.time then
            return
        end
    end

    gRankMgr_Clear(RANK_DEFINE_OPERATION_94)

    local day = oper_act_94_get_day_by_cfg(cfg)
    --print(" start day ="..day )
    if day ~= 1 then
        return
    end
    local players = LuaHelp.getAllActorList()
    local miniTime = System.getCurrMiniTime()
    local time = System.getSystemTime()
    if players then 
        for k, v in ipairs(players) do  
            local actorid = Actor.getActorId(v)
            local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_94, 1)
            local myData = BaseFuc_unserialize(data)
            if not myData then
                myData = {}
            end
            if not myData.myOnlineTime then
                myData.myOnlineTime = {}
            end
            if not myData.dailyStartTime then
                myData.dailyStartTime = miniTime
            end

            myData.dailyStartTime = miniTime
            myData.myOnlineTime[day] = 0

            myData.day = day

            if not myData.cmd_id then
                myData.cmd_id = cfg.cmd_id
                myData.act_id = cfg.act_id
                myData.time = time
            end

            local newData = BaseFuc_serialize(myData)
            gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_94, 1, newData)
        end
    end
end

-- 活动结束
function oper_act_94_end(cfg)
    local ssVar = System.getStaticVar()
    ssVar.oper_act_94_start = nil
    ssVar.oper_act_94_cmd = nil
    ssVar.oper_act_94_act = nil

    if not cfg then return end
    local config = cfg.config
    if not config then return end
end

-- 打包数据
function oper_act_94_packet_data(sysarg, cfg)

    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_94_start then
        return
    end
    if not cfg then return end
    local config = cfg.config
    if not config then return end

    local day = oper_act_94_get_day_by_cfg(cfg)
    --print(" data day ="..day )

    local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_94, 1)

    local myData = BaseFuc_unserialize(data)
        
    if not myData then
        myData = {}
    end

    if not myData.myAwardData then
        myData.myAwardData = {}
    end

    if not myData.myOnlineTime then
        myData.myOnlineTime = {}
    end

    if not myData.myOnlineTime[day] then
        myData.myOnlineTime[day] = 0
    end

    local miniTime = System.getCurrMiniTime()

    if not myData.dailyStartTime then
        myData.dailyStartTime = miniTime
    end

    if myData.day then
        day = myData.day
    end

    --print(" data day2 ="..day )
    myData.myOnlineTime[day] = myData.myOnlineTime[day] + miniTime - myData.dailyStartTime

    local pack = oper_act_alloc_init_data_packet(sysarg, cfg.cmd_id, cfg.act_id)
    if (pack == nil) then
        return
    end
    DataPack.writeByte(pack, day)
    DataPack.writeByte(pack, day)
    for idx = 1, day do
        local todayTime
        if idx == day then
            todayTime = myData.myOnlineTime[day]
        else
            todayTime = myData.myOnlineTime[idx] or -1
        end
        --print("todayTime ="..todayTime)
        DataPack.writeInt(pack, todayTime)
        if not myData.myAwardData[idx] then
            myData.myAwardData[idx] = {}
        end
        local ii = idx
        if idx > #config.Rewards then
            ii = #config.Rewards
        end
        local myConfig = config.Rewards[ii]
        local len = #myConfig
        DataPack.writeByte(pack, len)
        for iii = 1, len do
            local state = 0
            if myData.myAwardData[idx][iii] and myData.myAwardData[idx][iii] == 2 then
                state = myData.myAwardData[idx][iii]
            elseif todayTime >= myConfig[iii].online then
                state = 1
            end
            DataPack.writeByte(pack, state)
        end
    end
    DataPack.flush(pack)
    
    --DataPack.writeByte(netPack, 1)        -- 活动特有参数
end

-- 操作，返回操作结果，0为成功
function oper_act_94_do(sysarg, cfg, clientPkt)
    if cfg == nil then return end
    
    if cfg.state == nil or cfg.state ~= 1 then -- 不在活动中
        Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation001, ttFlyTip)
        return
    end
    
    local config = cfg.config
    if config == nil then -- 参数错误
        print("error, oper_act_94_do cfg.config confg error")
        return
    end
    local opType = DataPack.readByte(clientPkt)
    --print("opType ="..opType)
    local opDay = DataPack.readByte(clientPkt)
    --print("opDay ="..opDay)
    local opIndex = DataPack.readByte(clientPkt)
    --print("opIndex ="..opIndex)

    local day = oper_act_94_get_day_by_cfg(cfg)
    --print(" get day ="..day )

    local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_94, 1)
    local myData = BaseFuc_unserialize(data)

    if not myData then
        myData = {}
    end

    if myData.day then
        day = myData.day
    end

    --print(" get day2 ="..day )
    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_94_start then
        Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation004, ttFlyTip)
        return
    end

    if opDay > day then
        Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation237, ttFlyTip)
        return
    end

    if opType == 2 and opDay == day then
        Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation238, ttFlyTip)
        return
    end

    local curConfig = config.Rewards[opDay]
    if not curConfig then
        curConfig = config.Rewards[#config.Rewards]
    end

    if opIndex > #curConfig then
        Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation005, ttFlyTip)
        return
    end

    local awardConfig = curConfig[opIndex]
    if not awardConfig then
        return
    end


    if not myData.myAwardData then
        myData.myAwardData = {}
    end

    if not myData.myOnlineTime then
        myData.myOnlineTime = {}
    end

    if not myData.myAwardData[opDay] then
        myData.myAwardData[opDay] = {}
    end


    if myData.myAwardData[opDay][opIndex] and myData.myAwardData[opDay][opIndex] == 2 then
        Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation220, ttFlyTip)
        return
    end

    local miniTime = System.getCurrMiniTime()

    if not myData.dailyStartTime then
        myData.dailyStartTime = miniTime
    end

    if not myData.myOnlineTime[day] then
        myData.myOnlineTime[day] = 0
    end

    myData.myOnlineTime[day] = myData.myOnlineTime[day] + miniTime - myData.dailyStartTime

    if opType == 1 then
        local todayTime
        if opDay == day then
            todayTime = myData.myOnlineTime[day]
        else
            todayTime = myData.myOnlineTime[opDay] or -1
        end
        if not ((myData.myAwardData[opDay][opIndex] and myData.myAwardData[opDay][opIndex] == 1 ) or todayTime >= awardConfig.online) then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation006, ttFlyTip)
            return
        end
        if not IsBagGridEnough(sysarg, awardConfig.awards) then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.COM0015, ttFlyTip)
            return
        end
    elseif opType  == 2 then
        if opIndex ~= 1 then
            local yesTime = myData.myOnlineTime[opDay] or -1
            if not ((myData.myAwardData[opDay][opIndex-1] and myData.myAwardData[opDay][opIndex-1] >= 1 ) or yesTime >= awardConfig.online) then
                Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation239, ttFlyTip)
                return
            end
        end
        if not CheckConsumeCond( sysarg, awardConfig.goldGetConsumes, 1 ) then
            return
        end

        if not IsBagGridEnough(sysarg, awardConfig.awards) then
            Actor.sendTipmsg(sysarg, Lang.ScriptTips.COM0015, ttFlyTip)
            return
        end

        if not DoConsumeCond( sysarg, awardConfig.goldGetConsumes, 1, LogIds.OperationLogId094, Lang.LogTips.Operation094 ) then
            return
        end
    end

    myData.myAwardData[opDay][opIndex] = 2
    
    GiveCommonAward(sysarg, awardConfig.awards, LogIds.OperationLogId094, Lang.LogTips.Operation094)
    
    if not myData.cmd_id then
        myData.cmd_id = cfg.cmd_id
        myData.act_id = cfg.act_id
        myData.time = System.getSystemTime()
    end

    if not myData.sex then
        myData.sex = Actor.getIntProperty(sysarg, PROP_ACTOR_SEX)
        myData.vocation = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)
    end

    local newData = BaseFuc_serialize(myData)
    gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_94, 1, newData)
        
    local netPack = oper_act_alloc_do_result_packet(sysarg, cfg.cmd_id, cfg.act_id, 0)
    if not netPack then return end

    DataPack.writeByte(netPack, opDay) 
    DataPack.writeByte(netPack, opIndex) 
    DataPack.writeByte(netPack, 2) 

--  DataPack.writeByte(netPack, 1) -- 活动特有参数
    DataPack.flush(netPack)
end

-- 跨天
function oper_act_94_new_day_arrive(act_id) 
    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_94_start then
        return
    end
    if not ssVar.oper_act_94_cmd then
        return
    end
    if not ssVar.oper_act_94_act then
        return
    end
    local cfg = get_oper_act_cfg(ssVar.oper_act_94_cmd, ssVar.oper_act_94_act)
    if not cfg then
        return
    end
    local config = cfg.config
    if not config then return end
    local day = oper_act_94_get_day_by_cfg(cfg)
    --print(" cross day ="..day )
    if day == 1 then
        return
    end
    local players = LuaHelp.getAllActorList()
    local miniTime = System.getCurrMiniTime()
    local time = System.getSystemTime()
    if players then 
        for k, v in ipairs(players) do  
            local actorid = Actor.getActorId(v)
            local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_94, 1)
            local myData = BaseFuc_unserialize(data)
            if not myData then
                myData = {}
            end

            if myData.day and myData.day ~= day then
                --print(" cross myData.day ="..myData.day )
                if not myData.myOnlineTime then
                    myData.myOnlineTime = {}
                end
                if not myData.dailyStartTime then
                    myData.dailyStartTime = miniTime
                end
                myData.myOnlineTime[myData.day] = (myData.myOnlineTime[myData.day] or 0) + miniTime - myData.dailyStartTime

                myData.dailyStartTime = miniTime
                myData.myOnlineTime[day] = 0

                if not myData.cmd_id then
                    myData.cmd_id = cfg.cmd_id
                    myData.act_id = cfg.act_id
                    myData.time = time
                end
                myData.day = day

                local newData = BaseFuc_serialize(myData)
                gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_94, 1, newData)
            end
        end
    end
end

--登入
function oper_act_94_login(sysarg)
    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_94_start then
        return
    end
    if not ssVar.oper_act_94_cmd then
        return
    end
    if not ssVar.oper_act_94_act then
        return
    end
    local cfg = get_oper_act_cfg(ssVar.oper_act_94_cmd, ssVar.oper_act_94_act)
    if not cfg then
        return
    end
    local config = cfg.config
    if not config then return end


    local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_94, 1)

    local myData = BaseFuc_unserialize(data)
    

    if not myData then
        myData = {}
    end

    if not myData.myOnlineTime then
        myData.myOnlineTime = {}
    end

    local day = oper_act_94_get_day_by_cfg(cfg)
    --print("login day ="..day)

    if not myData.myOnlineTime[day] then
        myData.myOnlineTime[day] = 0
    end

    local miniTime = System.getCurrMiniTime()
    local time = System.getSystemTime()
 
    
    myData.dailyStartTime = miniTime
    myData.day = day

    if not myData.cmd_id then
        myData.cmd_id = cfg.cmd_id
        myData.act_id = cfg.act_id
        myData.time = time
    end

    local newData = BaseFuc_serialize(myData)
    gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_94, 1, newData)

end

--登出
function oper_act_94_logout(sysarg)
    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_94_start then
        return
    end
    if not ssVar.oper_act_94_cmd then
        return
    end
    if not ssVar.oper_act_94_act then
        return
    end
    local cfg = get_oper_act_cfg(ssVar.oper_act_94_cmd, ssVar.oper_act_94_act)
    if not cfg then
        return
    end
    local config = cfg.config
    if not config then return end

    local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_94, 1)

    local myData = BaseFuc_unserialize(data)
    

    if not myData then
        myData = {}
    end

    local time = System.getSystemTime()
    local day = oper_act_94_get_day_by_cfg(cfg)
    --print(" logout day ="..day )
    if myData.day then
        day = myData.day
    end
    --print(" logout day2 ="..day )
    local miniTime = System.getCurrMiniTime()
    
    if not myData.myOnlineTime then
        myData.myOnlineTime = {}
    end

    if not myData.dailyStartTime then
        myData.dailyStartTime = miniTime
    end

    if not myData.myOnlineTime[day] then
        myData.myOnlineTime[day] = 0
    end

    myData.myOnlineTime[day] = myData.myOnlineTime[day] + miniTime - myData.dailyStartTime

    myData.dailyStartTime = nil

    if not myData.cmd_id then
        myData.cmd_id = cfg.cmd_id
        myData.act_id = cfg.act_id
        myData.time = time
    end

    local newData = BaseFuc_serialize(myData)
    gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_94, 1, newData)
end

function oper_act_94_get_day_by_cfg(cfg)
    local index = 1
    local time = System.getSystemTime()
    --print("time ="..time)
    local second = System.getCurrMiniTime() - System.getToday()
    local zeroTime = time - second
    --print("zeroTime ="..zeroTime)
    --print("cfg.beg_time ="..cfg.beg_time)
    if zeroTime > cfg.beg_time then
        index = math.floor((zeroTime - cfg.beg_time) / 86400) + 1
        if (zeroTime - cfg.beg_time) % 86400 ~= 0 then
            index = index + 1
        end
    end

    return index
end

